﻿using DotNetHackathon.GBA.ApiCommon;
using Microsoft.AspNetCore.Mvc;
using Vaccination.API.Models;
using Vaccination.API.Repositories;

namespace Vaccination.API.Controllers
{
    /// <summary>
    /// 疫苗管理 api
    /// </summary>
    [ApiController]
    [Route("api/v1/vaccination")]
    public class VaccinationController : ControllerBase
    {
        private readonly IVaccinationInfoRepository _vaccinationInfoRepository;

        public VaccinationController(IVaccinationInfoRepository vaccinationInfoRepository)
        {
            _vaccinationInfoRepository = vaccinationInfoRepository;
        }

        /// <summary>
        /// 获取疫苗接种信息
        /// </summary>
        /// <param name="id">疫苗信息Id</param>
        /// <returns></returns>
        [Route("info/{id}")]
        [HttpGet]
        public async Task<ActionResult> GetVaccinationInfoAsync(Guid id)
        {
            var vaccinationInfo = await _vaccinationInfoRepository.GetByIdAsync(id);

            if (vaccinationInfo == null)
            {
                return Ok(vaccinationInfo);
            }

            return Ok(MapFrom(vaccinationInfo));
        }

        /// <summary>
        /// 删除疫苗接种信息
        /// </summary>
        /// <param name="id">疫苗信息Id</param>
        /// <returns></returns>
        [Route("info/{id}")]
        [HttpDelete]
        public async Task<ActionResult> DeleteVaccinationInfoAsync(Guid id)
        {
            await _vaccinationInfoRepository.DeleteAsync(id);
            return Ok();
        }

        /// <summary>
        /// 获取疫苗信息
        /// </summary>
        /// <param name="id">疫苗信息Id</param>
        /// <returns></returns>
        [Route("info/list")]
        [HttpPost]
        public async Task<ActionResult> GetVaccinationInfoByPageAsync([FromBody] VaccinationPageInput pageInput)
        {
            var (total, items) = await _vaccinationInfoRepository.GetByPage(pageInput);
            var vaccinationInfos = new List<VaccinationInfoDto>();

            foreach (var vaccinationInfo in items)
            {
                vaccinationInfos.Add(MapFrom(vaccinationInfo));
            }

            return Ok(new PaginatedResult<VaccinationInfoDto>() { Items = vaccinationInfos, Total = total });
        }

        /// <summary>
        /// 新建接种（预约）信息
        /// </summary>
        /// <param name="vaccinationInfoInput">疫苗接种（预约）信息</param>
        /// <returns></returns>
        [HttpPost("info")]
        public async Task<ActionResult> CreateVaccinationInfoAsync([FromBody] CreateVaccinationInfoInput vaccinationInfoInput)
        {
            var vaccinationInfo = new VaccinationInfo()
            {
                Id = Guid.NewGuid(),
                CreatedTime = DateTime.Now,
                BookedTime = vaccinationInfoInput.BookedTime,
                Status = 1,
                UserId = vaccinationInfoInput.UserId,
                UserName = vaccinationInfoInput.UserName,
                VaccineId = vaccinationInfoInput.VaccineId,
                VaccineName = vaccinationInfoInput.VaccineName
            };

            vaccinationInfo = await _vaccinationInfoRepository.AddAsync(vaccinationInfo);

            return Ok(MapFrom(vaccinationInfo));
        }

        /// <summary>
        /// 更新接种（预约）信息
        /// </summary>
        /// <param name="updateVaccinationInfo">更新输入</param>
        /// <returns></returns>
        [Route("info")]
        [HttpPut]
        public async Task<ActionResult> UpdateVaccinationInfoAsync([FromBody] UpdateVaccinationInfoInput updateVaccinationInfo)
        {
            var vaccinationInfo = await _vaccinationInfoRepository.GetByIdAsync(updateVaccinationInfo.Id);

            if (vaccinationInfo == null)
            {
                throw new BusinessException("notfound", "疫苗接种（预约）信息不存在");
            }

            if (vaccinationInfo.Status == 2)
            {
                throw new BusinessException("error", "已接种，无法修改预约接种信息");
            }

            if (vaccinationInfo.Status == 3)
            {
                throw new BusinessException("error", "已取消预约，无法修改预约接种信息");
            }

            switch (updateVaccinationInfo.Status)
            {
                case 2:
                    vaccinationInfo.CompletedTime = DateTime.Now;
                    vaccinationInfo.LastModifiedTime = DateTime.Now;
                    vaccinationInfo.Status = 2;
                    break;
                case 3:
                    vaccinationInfo.LastModifiedTime = DateTime.Now;
                    vaccinationInfo.Status = 2;
                    break;
            }

            await _vaccinationInfoRepository.UpdateAsync(vaccinationInfo);

            return Ok();
        }

        private static VaccinationInfoDto MapFrom(VaccinationInfo vaccinationInfo)
        {
            return new VaccinationInfoDto()
            {
                Id = vaccinationInfo.Id,
                BookedTime = vaccinationInfo.BookedTime,
                CompletedTime = vaccinationInfo.CompletedTime,
                CreatedTime = vaccinationInfo.CreatedTime,
                Status = vaccinationInfo.Status,
                UserId = vaccinationInfo.UserId,
                UserName = vaccinationInfo.UserName,
                VaccineId = vaccinationInfo.VaccineId,
                VaccineName = vaccinationInfo.VaccineName
            };
        }
    }
}
